package com.gict.antifraudback.controller.web.menu;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gict.antifraudback.entity.Menu;
import com.gict.antifraudback.exception.MyException;
import com.gict.antifraudback.result.ResultEnum;
import com.gict.antifraudback.result.ResultView;
import com.gict.antifraudback.service.MenuService;
import com.gict.antifraudback.vo.MenuVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * @author ThinkPad
 */
@RestController
@Slf4j
@RequestMapping("/wapi/menu")
public class MenuController {

    @Autowired
    private MenuService menuService;

    @GetMapping("/getList")
    public ResultView getList(MenuVo menuVo) {
        LambdaQueryWrapper<Menu> wrapper = Wrappers.lambdaQuery();
        wrapper.like(!ObjectUtils.isEmpty(menuVo.getName()), Menu::getName, menuVo.getName());
        return ResultView.ok(menuService.page(new Page<>(menuVo.getCurrent(), menuVo.getPageSize()), wrapper));
    }

    @GetMapping("/getTree")
    public ResultView getTree(String name) {
        LambdaQueryWrapper<Menu> wrapper = Wrappers.lambdaQuery();
        wrapper.like(!ObjectUtils.isEmpty(name), Menu::getName, name);

        List<Menu> list = menuService.list(wrapper);
        return ResultView.ok(menuService.buildTree(list));
    }

    /**
     * 异步获取树的子节点
     *
     * @param id
     * @return
     */
    @GetMapping("/getTreeList")
    public ResultView getTreeList(@RequestParam(defaultValue = "0") Integer id) {
        LambdaQueryWrapper<Menu> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Menu::getParentId, id);

        List<Menu> list = menuService.list(wrapper);

        List<Map<String, Object>> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (Menu menu : list) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", menu.getId());
                map.put("pId", menu.getParentId());
                map.put("value", menu.getId());
                map.put("title", menu.getName());
                map.put("isLeaf", menu.getIsLeaf().equals(1));
                result.add(map);
            }
        }

        return ResultView.ok(result);
    }

    @GetMapping("/get")
    public ResultView get(@Valid @NotNull Integer id) {
        Menu menu = menuService.getById(id);
        if (menu == null) {
            throw new MyException("菜单不存在");
        }
        return ResultView.ok(menu);
    }

    @PostMapping("/delete")
    public ResultView delete(@RequestBody ArrayList<Integer> ids) {
        log.info("menuVo:{}", ids);
        for (Integer id : ids) {
            Menu menu = menuService.getById(id);
            menuService.removeById(id);
            // 修改父节点
            if (menu.getParentId() != null && menu.getParentId() != 0){
                LambdaQueryWrapper<Menu> wrapper = Wrappers.lambdaQuery();
                wrapper.eq(Menu::getParentId, menu.getParentId());
                // 没有子节点需要修改父节点
                if (menuService.count(wrapper) == 0) {
                    Menu update = new Menu();
                    update.setId(menu.getParentId());
                    update.setIsLeaf(1);
                    menuService.updateById(update);
                }
            }
        }
        return ResultView.okMsg("删除成功");
    }

    @PostMapping("/add")
    public ResultView add(@Valid @RequestBody Menu menu) {
        this.createBefore(menu);
        // fixme 此处应该有事务管理
        // 如果是子节点需要修改父节点
        if (menu.getParentId() != null){
            Menu parent = menuService.getById(menu.getParentId());
            parent.setIsLeaf(0);
            menuService.updateById(parent);
        }
        menuService.save(menu);
        return ResultView.ok();
    }

    /**
     * 创建前检查
     */
    private void createBefore(Menu menu) {
        LambdaQueryWrapper<Menu> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Menu::getName, menu.getName());
        Menu exists = menuService.getOne(wrapper);

        if (exists != null && !exists.getId().equals(menu.getId())) {
            throw new MyException(ResultEnum.CODE_2, "该菜单已经存在");
        }
    }

    @PostMapping("/update")
    public ResultView update(@RequestBody @Valid Menu menu) {
        Menu update = menuService.getById(menu.getId());
        if (update == null) {
            return ResultView.error(ResultEnum.CODE_2, "数据不存在！");
        }
        createBefore(menu);
        menuService.updateById(menu);
        return ResultView.ok();
    }
}
